import axios, { type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type AxiosError, type InternalAxiosRequestConfig } from 'axios'
import { ElMessage } from 'element-plus'
import qs from 'qs'

// 请求配置接口
export interface RequestConfig extends AxiosRequestConfig {
  showLoading?: boolean
  showError?: boolean
  showSuccess?: boolean
  successMessage?: string
}

// 响应数据接口
export interface ResponseData<T = any> {
  code: number
  data: T
  message: string
  success: boolean
}

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || (import.meta.env.DEV ? '/api' : 'https://fc-mp-77def827-a81a-4125-8389-94d01ea341a3.next.bspapp.com/api'), // 从环境变量获取基础URL
  timeout: 10000, // 请求超时时间
  headers: {
    'Content-Type': 'application/json;charset=UTF-8'
  }
})

// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    // 在发送请求之前做些什么
    
    // 获取token (如果有的话)
    const token = localStorage.getItem('token') || sessionStorage.getItem('token')
    if (token) {
      config.headers = config.headers || {}
      config.headers.Authorization = `Bearer ${token}`
    }

    // 处理 POST 请求的数据格式
    if (config.method === 'post' && config.data) {
      // 如果是 FormData 类型，不处理
      if (!(config.data instanceof FormData)) {
        // 如果 Content-Type 是 application/x-www-form-urlencoded，使用 qs 序列化
        if (config.headers['Content-Type'] === 'application/x-www-form-urlencoded') {
          config.data = qs.stringify(config.data)
        }
      }
    }

    // 处理 GET 请求的参数序列化
    if (config.method === 'get' && config.params) {
      config.paramsSerializer = (params) => {
        return qs.stringify(params, { arrayFormat: 'brackets' })
      }
    }

    return config
  },
  (error: AxiosError) => {
    // 对请求错误做些什么
    console.error('请求错误:', error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse<ResponseData>) => {
    // 对响应数据做点什么
    const res = response.data
    const config = response.config as RequestConfig

    // 如果返回的状态码为200，说明接口请求成功，可以正常拿到数据
    if (response.status === 200) {
      // 根据业务状态码判断请求是否成功
      if (res.code === 200 || res.success === true) {
        // 显示成功消息（如果配置了的话）
        if (config.showSuccess && config.successMessage) {
          ElMessage.success(config.successMessage)
        }
        return response
      } else {
        // 业务错误处理
        const errorMsg = res.message || '请求失败'
        if (config.showError !== false) {
          ElMessage.error(errorMsg)
        }
        return Promise.reject(new Error(errorMsg))
      }
    } else {
      ElMessage.error('网络错误')
      return Promise.reject(new Error('网络错误'))
    }
  },
  (error: AxiosError) => {
    // 对响应错误做点什么
    let message = '请求失败'
    const config = error.config as RequestConfig

    if (error.response) {
      const status = error.response.status
      switch (status) {
        case 400:
          message = '请求参数错误'
          break
        case 401:
          message = '未授权，请重新登录'
          // 清除本地存储的用户信息
          localStorage.removeItem('token')
          sessionStorage.removeItem('token')
          // 可以在这里跳转到登录页面
          // router.push('/login')
          break
        case 403:
          message = '拒绝访问'
          break
        case 404:
          message = '请求资源不存在'
          break
        case 408:
          message = '请求超时'
          break
        case 500:
          message = '服务器内部错误'
          break
        case 501:
          message = '服务未实现'
          break
        case 502:
          message = '网关错误'
          break
        case 503:
          message = '服务不可用'
          break
        case 504:
          message = '网关超时'
          break
        case 505:
          message = 'HTTP版本不受支持'
          break
        default:
          message = `连接错误${status}`
      }
    } else if (error.code === 'ECONNABORTED') {
      message = '请求超时'
    } else if (error.message.includes('Network Error')) {
      message = '网络连接异常'
    }

    // 显示错误消息（除非明确配置不显示）
    if (config?.showError !== false) {
      ElMessage.error(message)
    }

    console.error('响应错误:', error)
    return Promise.reject(error)
  }
)

export default service
